package com.ppt.android.common


import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import com.google.auto.service.AutoService
import com.ppt.android.base.BaseApplication
import com.ppt.android.base.app.ApplicationLifecycle
import com.ppt.android.base.utils.*
import com.ppt.android.base.utils.network.NetworkStateClient
import com.ppt.android.common.helper.UploadHelper
import me.jessyan.autosize.AutoSizeConfig


/**
 * 项目相关的Application
 *
 * @author ZouJiaCai
 * @since 4/16/21 3:37 PM
 */
@AutoService(ApplicationLifecycle::class)
class CommonApplication : ApplicationLifecycle, ForegroundBackgroundObserver {

    companion object {
        // 全局CommonApplication
        @SuppressLint("StaticFieldLeak")
        lateinit var mCommonApplication: CommonApplication
    }

    /**
     * 同[Application.attachBaseContext]
     * @param context Context
     */
    override fun onAttachBaseContext(context: Context) {
        mCommonApplication = this
    }

    /**
     * 同[Application.onCreate]
     * @param application Application
     */
    override fun onCreate(application: Application) {}

    /**
     * 同[Application.onTerminate]
     * @param application Application
     */
    override fun onTerminate(application: Application) {}

    /**
     * 主线程前台初始化
     * @return MutableList<() -> String> 初始化方法集合
     */
    override fun initByFrontDesk(): MutableList<() -> String> {
        val list = mutableListOf<() -> String>()
        // 以下只需要在主进程当中初始化 按需要调整
        if (ProcessUtils.isMainProcess(BaseApplication.context)) {
            list.add { initMMKV() }
            list.add { initNetworkStateClient() }
        }
        list.add { initOkHttpUtils()}
        list.add { initAndroidCodeUtils() }
        return list
    }





    private fun initOkHttpUtils(): String{
        UploadHelper.initClient()
        return "OkHttpUtils -->> init complete"
    }

    private fun initAndroidCodeUtils(): String{

        val config = LogUtils.getConfig() // 设置 log 总开关，包括输出到控制台和文件，默认开
            .setLogSwitch(isDebug()) // 设置是否输出到控制台开关，默认开
            .setConsoleSwitch(isDebug()) // 设置 log 全局标签，默认为空
            .setGlobalTag(null) // 当全局标签不为空时，我们输出的 log 全部为该 tag，
            // 为空时，如果传入的 tag 为空那就显示类名，否则显示 tag
            // 设置 log 头信息开关，默认为开
            .setLogHeadSwitch(true) // 打印 log 时是否存到文件的开关，默认关
            .setLog2FileSwitch(false) // 当自定义路径为空时，写入应用的/cache/log/目录中
            .setDir("") // 当文件前缀为空时，默认为"util"，即写入文件为"util-yyyy-MM-dd.txt"
            .setFilePrefix("") // 输出日志是否带边框开关，默认开
            .setBorderSwitch(true) // 一条日志仅输出一条，默认开，为美化 AS 3.1 的 Logcat
            .setSingleTagSwitch(true) // log 的控制台过滤器，和 logcat 过滤器同理，默认 Verbose
            .setConsoleFilter(LogUtils.V) // log 文件过滤器，和 logcat 过滤器同理，默认 Verbose
            .setFileFilter(LogUtils.V) // log 栈深度，默认为 1
            .setStackDeep(1) // 设置栈偏移，比如二次封装的话就需要设置，默认为 0
            .setStackOffset(0) // 设置日志可保留天数，默认为 -1 表示无限时长
            .setSaveDays(3) // 新增 ArrayList 格式化器，默认已支持 Array, Throwable, Bundle, Intent 的格式化输出
            .addFormatter(object : LogUtils.IFormatter<ArrayList<*>>() {
                override fun format(list: ArrayList<*>): String {
                    return "LogUtils Formatter ArrayList { $list }"
                }
            })
        LogUtils.i(config.toString())

        // AndroidAutoSize 是否开启log
        AutoSizeConfig.getInstance().setLog(isDebug())

        return "AndroidCodeUtils -->> init complete"
    }

    /**
     * 不需要立即初始化的放在这里进行后台初始化
     */
    override fun initByBackstage() {
    }

    /**
     * 初始化网络状态监听客户端
     * @return Unit
     */
    private fun initNetworkStateClient(): String {
        NetworkStateClient.register()
        return "NetworkStateClient -->> init complete"
    }


    /**
     * 腾讯 MMKV 初始化
     */
    private fun initMMKV(): String {
        val result = SpUtils.initMMKV(BaseApplication.context)
        return "MMKV -->> $result"
    }





    override fun foregroundBackgroundNotify(isForeground: Boolean) {
        LogUtils.d("ForegroundBackground", "isForeground: $isForeground")
    }
}